package cn.itcast.wanxinp2p.account.service.impl;

import cn.itcast.wanxinp2p.account.common.AccountErrorCode;
import cn.itcast.wanxinp2p.account.entity.Account;
import cn.itcast.wanxinp2p.account.mapper.AccountMapper;
import cn.itcast.wanxinp2p.account.service.AccountService;
import cn.itcast.wanxinp2p.api.account.model.AccountDTO;
import cn.itcast.wanxinp2p.api.account.model.AccountLoginDTO;
import cn.itcast.wanxinp2p.api.account.model.AccountRegisterDTO;
import cn.itcast.wanxinp2p.common.domain.RestResponse;
import cn.itcast.wanxinp2p.common.domain.StatusCode;
import cn.itcast.wanxinp2p.common.exception.BusinessException;
import cn.itcast.wanxinp2p.common.util.MD5Util;
import cn.itcast.wanxinp2p.common.util.PasswordUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;

@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private AccountMapper accountMapper;


    @Value("${sms.enable}")
    private Boolean enable;

    @Value("${sms.url}")
    private String url;

    /**
     * 远程调用 发送短信
     * @param mobile 手机号
     * @return
     */
    @Override
    public RestResponse getSMSCode(String mobile){
        /*发起远程请求调用 短信微服务 发送短信   RestTemplate
         http://localhost:56085/sailing/generate?effectiveTime=300&name=sms
         {"mobile":"13566668888"}
        返回数据：直接将短信服务的结果返回即可
            {
                "code": 0,
                "msg": "",
                "result": {
                    "key": "sms:70ba933b095b4b5c90ee314045fd9003",
                    "content": null
                }
            }
         */
        String nurl = url+"generate?effectiveTime=300&name=sms";
        Map<String,String> map = new HashMap<>();
        map.put("mobile",mobile);
        return restTemplate.postForObject(nurl, map, RestResponse.class);
    }


    /**
     * 验证码验证
     * @param mobile
     * @param key
     * @param code
     * @return
     */
    @Override
    public Integer checkMobile(String mobile, String key, String code){
          /* 1、远程调用 短信微服务 校验验证码是否正确
              Post请求：
              http://localhost:56085/sailing/verify?name=sms&verificationKey=sms:70ba933b095b4b5c90ee314045fd9003&verificationCode=707339
              根据结果判断验证码校验是否成功，如果失败，则抛出 AccountErrorCode.E_140152 异常

                访问路径：http://localhost:56085/sailing / verify?name=sms & verificationKey=xxx & verificationCode=xxx
                verificationKey表示校验标识，verificationCode标识验证码

            2、如果验证码正确，还需要根据手机号 去 account 表中查询手机号是否存在
            	如果存在返回 1，否则返回 0
        */

        Map<String,String> hashMap = new HashMap<>();
        hashMap.put("key",key);
        hashMap.put("code",code);

        String nurl = url+"verify?name=sms&verificationKey="+key+"&verificationCode="+code;
        RestResponse response = restTemplate.postForObject(nurl, hashMap, RestResponse.class);

        boolean result = (boolean)response.getResult();

        if (!result){
            throw new BusinessException(AccountErrorCode.E_140152);
        }

        // 根据手机号查询 数据
        Integer account = accountMapper.query(mobile);


        /* 返回结果：
        {
            "code": 0,
            "msg": "",
            "result": 1(成功) / 0(失败)
        }
        */
        return account > 0 ? 0:1;

    }


    /**
     * 账户注册
     * @param registerDTO 注册信息
     * @return
     */
    @Override
    public AccountDTO register(AccountRegisterDTO registerDTO) {

        // 加盐+密码
//        String generate = PasswordUtil.generate(registerDTO.getPassword());
//
//        Account account = new Account();
//        BeanUtils.copyProperties(registerDTO,account);
//        account.setSalt(generate);
//        account.setDomain("c");
//
//        // Account微服务会把数据保存到p2p_account数据库的account表中
//        accountMapper.save(account);
//
//        AccountDTO accountDTO = new AccountDTO();
//        BeanUtils.copyProperties(account,accountDTO);
//
//        return accountDTO;

        Account account = new Account();
        account.setUsername(registerDTO.getUsername());
        account.setMobile(registerDTO.getMobile());
        account.setPassword(PasswordUtil.generate(registerDTO.getPassword()));

        if (enable){
            account.setPassword(PasswordUtil.generate(account.getMobile()));
        }
        account.setDomain("c");
        account.setStatus(StatusCode.STATUS_OUT.getCode());
        accountMapper.save(account);
        return convertAccountEntityToDTO(account);
    }


    /**
     * 登录
     * @param accountLoginDTO 封装登录请求数据
     * @return
     */
    @Override
    public AccountDTO login(AccountLoginDTO accountLoginDTO) {
        //1、查询用户，注意此处需要根据前端传递的 AccountLoginDTO的domain做判断：
        String domain = accountLoginDTO.getDomain();

        Account account = null;

        if (domain.equalsIgnoreCase("c")){
            //  如果值是 c 表示是c端用户，需要根据手机号查询
            account = accountMapper.queryAccount(accountLoginDTO.getMobile());
        }else {
            //  否则是b端用户，需要根据用户名查询
            account = accountMapper.queryUsername(accountLoginDTO.getUsername());
        }
        // 根据用户没查询出数据
        if (account == null){
            //2、判断用户是否存在，如果不存在，直接抛出 AccountErrorCode.E_130104 异常
            throw new BusinessException(AccountErrorCode.E_130104);
        }


       AccountDTO accountDTO = convertAccountEntityToDTO(account);
        if (enable){
            return accountDTO;
        }

        if (PasswordUtil.verify(accountLoginDTO.getPassword(),account.getPassword())){
            return accountDTO;
        }
        throw new BusinessException(AccountErrorCode.E_130105);


//        if (!enable){
//            //4、验证密码，如果密码错误则抛出 AccountErrorCode.E_130105 异常
//            String password = query.getPassword();
//            boolean verify = PasswordUtil.verify(password, accountLoginDTO.getPassword());
//
//            if (!verify){
//                throw new BusinessException(AccountErrorCode.E_130105);
//            }
//        }
//        //3、如果 smsEnable=true ，说明是短信验证码登录，不做密码校验。直接返回
//
//        dto.setId(query.getId());
//        dto.setUsername(query.getUsername());
//        dto.setMobile(query.getMobile());
//        dto.setDomain(query.getDomain());
//        return dto;
    }

    // 设置值
    private AccountDTO convertAccountEntityToDTO(Account account) {
        if (account == null){
            return null;
        }
        AccountDTO dto = new AccountDTO();
        BeanUtils.copyProperties(account,dto);
        return dto;
    }
}
